﻿using Design.Common.Interface;
using System.Data;
using System.Reflection;

namespace DesignPatternDemo
{
    internal class DesignPatternManager
    {
        private IEnumerable<IDesignDemo> GetDesignDemos()
        {

            var appDirectory = System.Environment.CurrentDirectory;
            DirectoryInfo directoryInfo = new DirectoryInfo(appDirectory);
            FileInfo[] files = directoryInfo.GetFiles("*.dll");

            List<IDesignDemo> designDemos = new List<IDesignDemo>();
            foreach (FileInfo file in files)
            {
                try
                {
                    Assembly assembly = Assembly.LoadFrom(file.FullName);
                    Console.WriteLine($"Loaded assembly: {assembly.FullName}");

                    var types = assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IDesignDemo)));

                    foreach (var item in types)
                    {
                        if (item == null)
                            continue;
                        var typeName = item.FullName ?? string.Empty;
                        var designExample = item.Assembly.CreateInstance(item.FullName);
                        if (designExample is IDesignDemo designDemo) 
                            designDemos.Add(designDemo);
                    }

                    //var types = assemblies.SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IDesignDemo))));
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Failed to load assembly: {file.Name}, Error: {ex.Message}");
                }
            }
            return designDemos;
        }

        public void RunExample()
        {
            var designDemos = GetDesignDemos();
            if (designDemos == null || designDemos.Count() == 0)
            {
                Console.WriteLine($"Find DesignDmoe count = 0");
                return;
            }

            Console.WriteLine($"Find DesignDmoe count = {designDemos.Count()}");
            designDemos = designDemos.OrderBy(p=>p.GetDesignAttribute().Index);
            foreach (var item in designDemos)
            {
                var designAttribute = item.GetDesignAttribute();
                Console.WriteLine($"\r\n**{designAttribute.DesignType}_{designAttribute.Name} START");
                item.RunExample(true);
                Console.WriteLine($"**{designAttribute.DesignType}_{designAttribute.Name} END");
            }
        }
    }
}